using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CodRevit.Services
{
    /// <summary>
    /// 模拟选择服务实现
    /// </summary>
    public class SimulateSelectService : ISimulateSelectService, IDisposable
    {
        private CancellationTokenSource? _cancellationTokenSource;
        private bool _disposed = false;

        public SimulateSelectService()
        {
            // 在需要时创建 CancellationTokenSource
        }

        /// <summary>
        /// 获取可选择的元素列表
        /// </summary>
        public List<Element> GetSelectableElements(Document doc, Autodesk.Revit.DB.View view)
        {
            try
            {
                // 获取当前视图中的所有可见元素，只选择模型实体
                var collector = new FilteredElementCollector(doc, view.Id)
                    .WhereElementIsNotElementType()
                    .Where(e => e.Category != null && 
                               !string.IsNullOrEmpty(e.Name) &&
                               IsModelElement(e));

                return collector.ToList();
            }
            catch (Exception ex)
            {
                TaskDialog.Show("错误", $"获取元素时发生错误: {ex.Message}");
                return new List<Element>();
            }
        }

        /// <summary>
        /// 判断是否为模型实体元素
        /// </summary>
        private bool IsModelElement(Element element)
        {
            if (element?.Category == null) return false;

            var categoryId = element.Category.Id.IntegerValue;
            
            // 排除的类别ID列表（这些不是模型实体）
            var excludedCategories = new HashSet<int>
            {
                (int)BuiltInCategory.OST_Levels,              // 标高
                (int)BuiltInCategory.OST_Grids,               // 轴网
                (int)BuiltInCategory.OST_SectionBox,          // 剖面框
                (int)BuiltInCategory.OST_Cameras,             // 相机
                (int)BuiltInCategory.OST_Views,               // 视图
                (int)BuiltInCategory.OST_Sheets,              // 图纸
                (int)BuiltInCategory.OST_Schedules,           // 明细表
                (int)BuiltInCategory.OST_Viewports,           // 视口
                (int)BuiltInCategory.OST_ReferencePoints,     // 参照点
                (int)BuiltInCategory.OST_Constraints,         // 约束
                (int)BuiltInCategory.OST_Dimensions,          // 尺寸标注
                (int)BuiltInCategory.OST_TextNotes,           // 文字注释
                (int)BuiltInCategory.OST_Tags,                // 标记
                (int)BuiltInCategory.OST_MultiCategoryTags,   // 多类别标记
                (int)BuiltInCategory.OST_AreaTags,            // 面积标记
                (int)BuiltInCategory.OST_RoomTags,            // 房间标记
                (int)BuiltInCategory.OST_Matchline,           // 匹配线
                (int)BuiltInCategory.OST_ReferenceViewer,     // 参照查看器
                (int)BuiltInCategory.OST_PointClouds,         // 点云
                (int)BuiltInCategory.OST_Lines,               // 线条
                (int)BuiltInCategory.OST_SketchLines,         // 草图线
                (int)BuiltInCategory.OST_CLines,              // C线
                (int)BuiltInCategory.OST_AnalyticalNodes,     // 分析节点
                (int)BuiltInCategory.OST_LoadCases,           // 荷载工况
                (int)BuiltInCategory.OST_BoundaryConditions,  // 边界条件
                (int)BuiltInCategory.OST_InternalLoads,       // 内部荷载
                (int)BuiltInCategory.OST_PointLoads,          // 点荷载
                (int)BuiltInCategory.OST_LineLoads,           // 线荷载
                (int)BuiltInCategory.OST_AreaLoads,           // 面荷载
            };

            // 如果在排除列表中，则不是模型实体
            if (excludedCategories.Contains(categoryId))
            {
                return false;
            }

            // 进一步检查元素类型
            // 排除注释类元素
            if (element is Dimension || 
                element is TextNote || 
                element is IndependentTag ||
                element is SpatialElementTag ||
                element is AreaTag)
            {
                return false;
            }

            // 排除视图相关元素
            if (element is Autodesk.Revit.DB.View ||
                element is ViewSheet ||
                element is Viewport)
            {
                return false;
            }

            // 排除基准元素
            if (element is Level ||
                element is Grid ||
                element is ReferencePlane)
            {
                return false;
            }

            // 只选择有几何形状的实体元素
            try
            {
                var geometry = element.get_Geometry(new Options());
                if (geometry == null) return false;

                // 检查是否有实际的几何体
                foreach (GeometryObject geomObj in geometry)
                {
                    if (geomObj is Solid solid && solid.Volume > 0)
                        return true;
                    if (geomObj is GeometryInstance)
                        return true;
                    if (geomObj is Mesh)
                        return true;
                    if (geomObj is Face)
                        return true;
                }
            }
            catch
            {
                // 如果获取几何体失败，保守地认为不是模型实体
                return false;
            }

            return false;
        }

        /// <summary>
        /// 开始模拟选择过程
        /// </summary>
        public async Task StartSimulationAsync(UIDocument uidoc, List<Element> elements, double intervalSeconds = 2.0)
        {
            if (elements == null || !elements.Any())
            {
                TaskDialog.Show("提示", "没有找到可选择的元素");
                return;
            }

            // 创建新的 CancellationTokenSource
            _cancellationTokenSource?.Dispose();
            _cancellationTokenSource = new CancellationTokenSource();

            try
            {
                var token = _cancellationTokenSource.Token;
                
                foreach (var element in elements)
                {
                    // 检查是否被取消
                    if (token.IsCancellationRequested)
                    {
                        break;
                    }

                    // 选择当前元素
                    var elementIds = new List<ElementId> { element.Id };
                    uidoc.Selection.SetElementIds(elementIds);
                    
                    // 将选中的构件显示在视图中央
                    CenterElementInView(uidoc, element);
                    
                    // 刷新视图以显示选择效果
                    uidoc.RefreshActiveView();

                    // 等待指定时间，同时检查ESC键
                    await WaitWithCancellation((int)(intervalSeconds * 1000), token);
                }

                // 清除选择
                uidoc.Selection.SetElementIds(new List<ElementId>());
                uidoc.RefreshActiveView();
            }
            catch (OperationCanceledException)
            {
                // 用户取消操作，清除选择
                uidoc.Selection.SetElementIds(new List<ElementId>());
                uidoc.RefreshActiveView();
            }
            catch (Exception ex)
            {
                TaskDialog.Show("错误", $"模拟选择过程中发生错误: {ex.Message}");
            }
        }

        /// <summary>
        /// 取消模拟选择
        /// </summary>
        public void CancelSimulation()
        {
            if (!_disposed && _cancellationTokenSource != null && !_cancellationTokenSource.IsCancellationRequested)
            {
                _cancellationTokenSource.Cancel();
            }
        }

        /// <summary>
        /// 将元素居中显示在视图中
        /// </summary>
        private void CenterElementInView(UIDocument uidoc, Element element)
        {
            try
            {
                // 使用更简单的方法：通过UIDocument的ShowElements方法来居中显示元素
                var elementIds = new List<ElementId> { element.Id };
                uidoc.ShowElements(elementIds);
            }
            catch (Exception ex)
            {
                // 如果居中失败，不影响主要功能，只记录错误
                System.Diagnostics.Debug.WriteLine($"居中显示元素时发生错误: {ex.Message}");
            }
        }

        /// <summary>
        /// 等待指定时间，同时检查取消令牌和ESC键
        /// </summary>
        private async Task WaitWithCancellation(int milliseconds, CancellationToken token)
        {
            var endTime = DateTime.Now.AddMilliseconds(milliseconds);
            
            while (DateTime.Now < endTime)
            {
                // 检查取消令牌
                if (token.IsCancellationRequested)
                {
                    token.ThrowIfCancellationRequested();
                }

                // 检查ESC键
                if ((System.Windows.Forms.Control.ModifierKeys & Keys.None) == Keys.None && 
                    (GetAsyncKeyState(0x1B) & 0x8000) != 0) // ESC键
                {
                    _cancellationTokenSource.Cancel();
                    token.ThrowIfCancellationRequested();
                }

                // 处理Windows消息，保持UI响应
                System.Windows.Forms.Application.DoEvents();
                
                // 短暂延迟
                await Task.Delay(50, token);
            }
        }

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        private static extern short GetAsyncKeyState(int vKey);

        public void Dispose()
        {
            if (!_disposed)
            {
                _cancellationTokenSource?.Cancel();
                _cancellationTokenSource?.Dispose();
                _cancellationTokenSource = null;
                _disposed = true;
            }
        }
    }
}